package com.vanke.devops.domain.manager.aliyun.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.cms.model.v20170301.QueryMetricListRequest;
import com.aliyuncs.cms.model.v20170301.QueryMetricListResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.FormatType;
import com.vanke.core.util.CollectionUtil;
import com.vanke.core.util.DateUtil;
import com.vanke.core.util.JsonUtil;
import com.vanke.core.util.StringUtil;
import com.vanke.devops.domain.enums.AliyunMonitorErrorCode;
import com.vanke.devops.domain.manager.aliyun.AliyunMonitorManager;
import com.vanke.devops.domain.manager.aliyun.AliyunMonitorConstants;
import com.vanke.devops.domain.manager.aliyun.bean.DataPoints;
import com.vanke.devops.domain.manager.aliyun.bean.Node;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author 陈景阳
 * @since 2018/3/14
 */
@Service
public class AliyunMonitorManagerImpl implements AliyunMonitorManager {

    private static final Logger LOGGER = LoggerFactory.getLogger(AliyunMonitorManagerImpl.class);

    @Autowired
    private IAcsClient acsClient;

    @Override
    public Node getNodeInfo(String instanceId) {

        if(StringUtil.isEmpty(instanceId)){
            return null;
        }

        //当前消耗的总CPU百分比
        DataPoints cpuUsed = getDataPoints(instanceId, AliyunMonitorConstants.METRIC_CPU_TOTAL);

        //内存总量
        DataPoints memTotal = getDataPoints(instanceId, AliyunMonitorConstants.METRIC_MEMORY_TOTAL_SPACE);

        //内存使用
        DataPoints memUsed = getDataPoints(instanceId, AliyunMonitorConstants.METRIC_ACTUAL_USED_SPACE);

        //内存剩余
        DataPoints memFree = getDataPoints(instanceId, AliyunMonitorConstants.METRIC_FREE_SPACE);

        DataPoints memPercent = getDataPoints(instanceId,AliyunMonitorConstants.METRIC_USED_UTILIZATION);

        //硬盘总量
        DataPoints diskTotal = getDataPoints(instanceId, AliyunMonitorConstants.METRIC_DISK_TOTAL);

        //硬盘使用
        DataPoints diskUsed = getDataPoints(instanceId, AliyunMonitorConstants.METRIC_DISK_USAGE_USED);

        //硬盘剩余
        DataPoints diskFree  = getDataPoints(instanceId, AliyunMonitorConstants.METRIC_DISK_USAGE_FREE);

        DataPoints diskPercent = getDataPoints(instanceId,AliyunMonitorConstants.METRIC_DISK_USAGE_UTILIZATION);

        Node node = new Node();
        node.setCpuUsed(cpuUsed.getAverage());
        node.setMemoryTotal(memTotal.getAverage());
        node.setMemoryUsed(memUsed.getAverage());
        node.setMemoryFree(memFree.getAverage());
        node.setDiskTotal(diskTotal.getAverage());
        node.setDiskUsed(diskUsed.getAverage());
        node.setDiskFree(diskFree.getAverage());
        node.setMemoryUsedPercent(memPercent.getAverage());
        node.setDiskUsedPercent(diskPercent.getAverage());
        node.ToGB();
        if(LOGGER.isDebugEnabled()){
            LOGGER.info("node info : {}",node);
        }
        return node;
    }

    private DataPoints getDataPoints(String instanceId,String metric){

        QueryMetricListRequest request = new QueryMetricListRequest();

        request.setProject(AliyunMonitorConstants.PROJECT_ECS_DASHBOARD);

        request.setMetric(metric);
        request.setPeriod(AliyunMonitorConstants.PERIOD);
        //1分钟内的情况
        String startTime = DateUtil.formatDateTime(new DateTime().minusMinutes(1).toDate());
        request.setStartTime(startTime);
        String endTime = DateUtil.formatDateTime(new Date());
        request.setEndTime(endTime);

        JSONObject dim = new JSONObject();
        dim.put(AliyunMonitorConstants.INSTANT_ID, instanceId);
        request.setDimensions(dim.toJSONString());
        request.setAcceptFormat(FormatType.JSON);

        QueryMetricListResponse response = null;
        try {
            response = acsClient.getAcsResponse(request);
        } catch (ClientException e) {
            throw AliyunMonitorErrorCode.SERVER_ERROR.getException();
        }

        return getDataPoints(response);
    }

    private DataPoints getDataPoints(QueryMetricListResponse response){
        if(response == null){
            throw AliyunMonitorErrorCode.SERVER_ERROR.getException();
        }
        if(AliyunMonitorConstants.SUCCESS.equals(response.getCode())){
            String dataPoints = response.getDatapoints();
            dataPoints = dataPoints.replace("Maximum","maximum")
                    .replace("Minimum","minimum")
                    .replace("Average","average");

            List<DataPoints> list = JsonUtil.fromListJson(dataPoints, DataPoints.class);

            for(DataPoints item : list){
                if(AliyunMonitorConstants.ROOT_DISK_NAME.equals(item.getDiskname())){
                    return item;
                }
            }
            if(CollectionUtil.isNotEmpty(list) ){
                return list.get(0);
            }
        }
        LOGGER.error("aliyun response : {}",response.getMessage());
        throw AliyunMonitorErrorCode.SERVER_ERROR.getException();
    }
}
